/*
 * @Author: zhangzhiyu zhangzhiyu1126@163.com
 * @Date: 2024-07-19 14:30:16
 * @LastEditors: Du Weixing duweixing@sgsimulation.com
 * @LastEditTime: 2024-12-06 22:17:57
 * @FilePath: \SGFEM\Solver\SectionCalculator\BeamSection\NumericalMethod\src\Box1SectionNumericalCalculator.cpp
 * @Description:
 *
 * Copyright (c) 2024 by 神工仿真, All Rights Reserved.
 */
#include "Box1SectionNumericalCalculator.h"

#include "DataStructure/Common/Real.h"

#include "SectionCalculator/StandardSectionTool.h"

using SG::Algebra::Point;
using SG::DataStructure::Common::Real;
using SG::DataStructure::FEM::PBARLData;
using SG::FEMSolver::Element::Box1SectionNumericalCalculator;

void Box1SectionNumericalCalculator::Mesh (const PBARLData& section, _OUT Meshes& meshes, int refineLevel) const
{
    // dimension 换算成 Ansys 的 wi、ti
    Real w1{ section.m_dimension[0] };
    Real w2{ section.m_dimension[1] };
    Real t1{ section.m_dimension[5] };
    Real t2{ section.m_dimension[4] };
    Real t3{ section.m_dimension[3] };
    Real t4{ section.m_dimension[2] };

    // refineLevel 为 Ansys 上 Coarse 到 Fine 的 0 到 5
    int n{ refineLevel + 1 };
    // 箱型划分8区格，角为 Square，竖直为 Vertical，水平为 Horizontal；nVertical、nHorizontal、nSquare 为该区格 y、z 方向上的网格数量
    int nSquare{ n };
    int nVerticalY{ n };
    int nVerticalZ{ 2 * n };
    int nHorizontalY{ 2 * n };
    int nHorizontalZ{ n };

    // 不动
    StandardSectionTool secMesh;
    Point               point;
    int                 nodeId{ 0 };
    int                 eleId{ 0 };
    Meshes              newMeshes;
    NodeSet             newEdgeNodes;
    int                 numRepeatNodes{ 0 };
    NodeSet             edgeNodes;

    // 1st block
    point.m_y = 0.0;
    point.m_z = 0.0;
    secMesh.MeshRect (point, t1, t3, nSquare, nSquare, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 2nd block
    point.m_y = w1 - t2;
    secMesh.MeshRect (point, t1 + t2 - w1, t3, nHorizontalY, nHorizontalZ, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * nSquare + 1;
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 3rd block
    point.m_y = w1;
    secMesh.MeshRect (point, -t2, t3, nSquare, nSquare, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * nSquare + 1;
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 4th block
    point.m_y = w1 - t2;
    point.m_z = w2 - t4;
    secMesh.MeshRect2 (point, t2, t3 + t4 - w2, nVerticalY, nVerticalZ, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * nSquare + 1;
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 5th block
    point.m_z = w2;
    secMesh.MeshRect2 (point, t2, -t4, nSquare, nSquare, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * nSquare + 1;
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 6th block
    point.m_y = t1;
    point.m_z = w2 - t4;
    secMesh.MeshRect (point, w1 - t1 - t2, t4, nHorizontalY, nHorizontalZ, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * nSquare + 1;
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 7th block
    point.m_y = 0.0;
    secMesh.MeshRect (point, t1, t4, nSquare, nSquare, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * nSquare + 1;
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 8th block
    point.m_z = t3;
    secMesh.MeshRect2 (point, t1, w2 - t3 - t4, nVerticalY, nVerticalZ, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * nSquare + 1;
    secMesh.Merge2 (edgeNodes, numRepeatNodes, newMeshes);
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId, numRepeatNodes);
}
